/**
 * Collaborative Story Development Web Application (CSDApp) 
 * Copyright Anton Strack 2014
 *
 * This file is part of Collaborative Story Development Application (CSDApp).
 *
 * CSDApp is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or any later version.
 *
 * CSDApp is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * CSDApp. If not, see <http://www.gnu.org/licenses/>.
 *
 */
package csdwa;

import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;

/**
 * This class handles csdwa authorization specific functionality, primarily when
 * to preform ownership checks of resources.
 *
 * @author Anton Strack
 */
public class AccessControl {

    private Authenticator authenticator = null;
    private Connection conn = null;
    private Authorizer authorizer = null;
    private User user = null;
    private HttpServletRequest request = null;

    public AccessControl(Connection conn) {
        this.conn = conn;
        this.authenticator = new Authenticator(conn);
        this.authorizer = new Authorizer(conn);
    }

    /**
     * This method authenticates the user according to their session.
     *
     * @param request the request object
     * @return a user with a role of the user as determined by the
     * authorization. If no password or proper session could be found for the
     * user, then the returned user is a guest user.
     */
    public User authenticate(HttpServletRequest request) {
        this.request = request;
        return this.authenticator.authenticate(request);
    }

    /**
     * This method authenticates the user by a user name and password.
     *
     * @param username the name of the user used to login
     * @param password the password of the user
     * @param request the request object.
     * @return a user with a role determined by the authorization. If no
     * password or proper session could be found for the user, then the returned
     * user is a guest user.
     */
    public User authenticateLogin(String username, String password, HttpServletRequest request) {
        return this.authenticator.authenticateLogin(username, password, request);
    }

    /**
     * Checks if the user is authorized to perform the action on the resource.
     *
     * @param user the user to check
     * @param actionId the action the user wants to preform
     * @param resourceTypeId the resource the action will be preformed on
     * @param resourceId the id of the specific resource.
     * @return true if the user is authorized and false if not.
     */
    public boolean isAuthorized(User user, int actionId, int resourceTypeId, int resourceId) {
        boolean isAuthorized;
        if (this.actionNeedOwnershipCheck(actionId)) {
            isAuthorized = this.authorizer.isAuthorized(user.getId(), user.getRoleId(), actionId, resourceTypeId, resourceId);
        } else {
            isAuthorized = this.authorizer.isAuthorizedNotOwned(user.getRoleId(), actionId, resourceTypeId);
        }
        return isAuthorized;
    }

    /**
     * Most action's don't require checking for resource ownership by the user.
     * This method checks to see if the action requires an ownership check.
     *
     * @param actionId the action id
     * @return true if the action requires checking if the user owns the
     * resource, otherwise false.
     */
    private boolean actionNeedOwnershipCheck(int actionId) {
        Map<Integer, Boolean> actMap = new HashMap<Integer, Boolean>(); // the integer is the action type id
        // add additional actions to this map to require ownership checks.
        actMap.put(InfoAggregator.getInstance().getActionTypeId("update"), true);//"update"
        actMap.put(InfoAggregator.getInstance().getActionTypeId("delete"), true);//"delete"

        if (actMap.containsKey(actionId)) {
            return true;
        }
        return false;
    }
}
